﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.CodeDom.Compiler;
using Microsoft.CSharp;

namespace DynamicFiltering
{
    public class CompilerWrapper
    {

        /// <summary>
        /// Method & class can't be static: would be very thread-unsafe (mutiple copies will inject their code into the same assembly).
        /// </summary>
        public CompilerResults Compile<DataContextType>( string code, List<string> additionalReferenceAssemblies = null )
        {
            using ( var compiler = new CSharpCodeProvider() )
            {
                var referencedAssemblies = ReferencedAssemblies( additionalReferenceAssemblies );
                referencedAssemblies.Add( typeof( DataContextType ).Module.Assembly.Location );
                var parameters = new CompilerParameters( referencedAssemblies.ToArray() ) { GenerateExecutable = false, GenerateInMemory = true, OutputAssembly = "DynamicAssembly", CompilerOptions = "/optimize" };
                return compiler.CompileAssemblyFromSource( parameters, new string[] { code } );
            }
        }

        private static List<string> ReferencedAssemblies( List<string> additionalReferenceAssemblies = null )
        {
            var result = new List<string>()
                        { 
                            "System.dll",
                            // dis where linq is
                            "System.Core.dll",
                            "EntityFramework.dll",
                            "System.Data.dll"
                        };
            if ( additionalReferenceAssemblies != null )
            {
                result.AddRange( additionalReferenceAssemblies );
            }
            return result;
        }

    }
}
